package com.zh.blog.strategy.impl;

import com.alibaba.fastjson2.JSON;
import com.zh.blog.common.api.StatusCodeEnum;
import com.zh.blog.config.QQConfigProperties;
import com.zh.blog.dto.QQTokenDto;
import com.zh.blog.dto.QQUserInfoDto;
import com.zh.blog.dto.SocialTokenDto;
import com.zh.blog.dto.SocialUserInfoDto;
import com.zh.blog.enums.LoginTypeEnum;
import com.zh.blog.exception.BizException;
import com.zh.blog.util.CommonUtils;
import com.zh.blog.vo.QQLoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static com.zh.blog.constant.SocialLoginConst.*;

/**
 * QQ登录策略实现
 * @author ZhengHao
 * Created At 2022/8/25.
 **/
@Service("qqLoginStrategyImpl")
public class QQLoginStrategyImpl extends AbstractSocialLoginStrategyImpl{
    @Autowired
    private QQConfigProperties qqConfigProperties;
    @Autowired
    private RestTemplate restTemplate;

    @Override
    public SocialUserInfoDto getSocialUserInfo(SocialTokenDto socialToken) {
        // 定义请求参数
        Map<String, String> formData = new HashMap<String, String>(3);
        formData.put(QQ_OPEN_ID, socialToken.getOpenId());
        formData.put(ACCESS_TOKEN, socialToken.getAccessToken());
        formData.put(OAUTH_CONSUMER_KEY, qqConfigProperties.getAppId());
        // 获取QQ返回的用户信息
        QQUserInfoDto qqUserInfoDto = JSON.parseObject(restTemplate.getForObject(qqConfigProperties.getUserInfoUrl(), String.class, formData), QQUserInfoDto.class);
        // 返回用户信息
        return SocialUserInfoDto.builder()
                .nickname(Objects.requireNonNull(qqUserInfoDto).getNickname())
                .avatar(qqUserInfoDto.getFigureurl_qq_1())
                .build();
    }

    @Override
    public SocialTokenDto getSocialToken(String data) {
        QQLoginVO qqLoginVO = JSON.parseObject(data, QQLoginVO.class);
        // 校验QQ token
        checkQQToken(qqLoginVO);
        // 返回token信息
        return SocialTokenDto.builder()
                .openId(qqLoginVO.getOpenId())
                .accessToken(qqLoginVO.getAccessToken())
                .loginType(LoginTypeEnum.QQ.getType())
                .build();
    }

    /**
     * 校验QQ token信息
     * @param qqLoginVO QQ登录信息
     */
    private void checkQQToken(QQLoginVO qqLoginVO) {
        // 根据token获取QQ openId信息
        Map<String, String> qqData = new HashMap<>(1);
        qqData.put(ACCESS_TOKEN,qqLoginVO.getAccessToken());
        try {
            String result = restTemplate.getForObject(qqConfigProperties.getCheckTokenUrl(), String.class, qqData);
            QQTokenDto qqTokenDto = JSON.parseObject(CommonUtils.getBracketsContent(Objects.requireNonNull(result)), QQTokenDto.class);
            // 判断openId是否一致
            if (!qqLoginVO.getOpenId().equals(qqTokenDto.getOpenid())) {
                throw new BizException(StatusCodeEnum.QQ_LOGIN_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(StatusCodeEnum.QQ_LOGIN_ERROR);
        }
    }
}